package utn.frba.matematicasuperior.controladores;

import java.util.List;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Dialogs;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import utn.frba.matematicasuperior.main.Main;
import utn.frba.matematicasuperior.modelo.ParOrdenado;
import utn.frba.matematicasuperior.modelo.PolinomioInterpolante;
import utn.frba.matematicasuperior.modelo.Soporte;
import utn.frba.matematicasuperior.utiles.Controlador;

public class PolinomioControlador implements Controlador {

	/************************************************************/
	/************************ ATRIBUTOS *************************/
	/************************************************************/

	private Main main;
	private PolinomioInterpolante polinomio;

	@FXML
	private ComboBox<String> cmbMetodoInterpolacion;

	@FXML
	private ComboBox<String> cmbCotaMaximaError;

	@FXML
	private Button btnCalcularPolinomio;

	@FXML
	private Button btnEvaluarPolinomio;

	@FXML
	private Button btnLimpiarTodo;

	@FXML
	private Button btnGraficarPolinomio;

	@FXML
	private TextArea consolaPolinomios;

	@FXML
	private CheckBox checkboxTruncarValores;

	@FXML
	private TextField txtGradoPolinomio;

	@FXML
	private TextField txtCantidadPuntosIngresados;

	/************************************************************/
	/*********************** PROPIEDADES ************************/
	/************************************************************/

	public Main getMain() {
		return main;
	}

	public void setMain(Main main) {
		this.main = main;
	}

	public PolinomioInterpolante getPolinomio() {
		return polinomio;
	}

	public void setPolinomio(PolinomioInterpolante polinomio) {
		this.polinomio = polinomio;
	}

	public ComboBox<String> getCmbMetodoInterpolacion() {
		return cmbMetodoInterpolacion;
	}

	public void setCmbMetodoInterpolacion(
			ComboBox<String> cmbMetodoInterpolacion) {
		this.cmbMetodoInterpolacion = cmbMetodoInterpolacion;
	}

	public ComboBox<String> getCmbCotaMaximaError() {
		return cmbCotaMaximaError;
	}

	public void setCmbCotaMaximaError(ComboBox<String> cmbCotaMaximaError) {
		this.cmbCotaMaximaError = cmbCotaMaximaError;
	}

	public Button getBtnCalcularPolinomio() {
		return btnCalcularPolinomio;
	}

	public void setBtnCalcularPolinomio(Button btnCalcularPolinomio) {
		this.btnCalcularPolinomio = btnCalcularPolinomio;
	}

	public Button getBtnEvaluarPolinomio() {
		return btnEvaluarPolinomio;
	}

	public void setBtnEvaluarPolinomio(Button btnEvaluarPolinomio) {
		this.btnEvaluarPolinomio = btnEvaluarPolinomio;
	}

	public Button getBtnLimpiarTodo() {
		return btnLimpiarTodo;
	}

	public void setBtnLimpiarTodo(Button btnLimpiarTodo) {
		this.btnLimpiarTodo = btnLimpiarTodo;
	}

	public Button getBtnGraficarPolinomio() {
		return btnGraficarPolinomio;
	}

	public void setBtnGraficarPolinomio(Button btnGraficarPolinomio) {
		this.btnGraficarPolinomio = btnGraficarPolinomio;
	}

	public TextArea getConsolaPolinomios() {
		return consolaPolinomios;
	}

	public void setConsolaPolinomios(TextArea consolaPolinomios) {
		this.consolaPolinomios = consolaPolinomios;
	}

	public CheckBox getCheckboxTruncarValores() {
		return checkboxTruncarValores;
	}

	public void setCheckboxTruncarValores(CheckBox checkboxTruncarValores) {
		this.checkboxTruncarValores = checkboxTruncarValores;
	}

	public TextField getTxtGradoPolinomio() {
		return txtGradoPolinomio;
	}

	public void setTxtGradoPolinomio(TextField txtGradoPolinomio) {
		this.txtGradoPolinomio = txtGradoPolinomio;
	}

	public TextField getTxtCantidadPuntosIngresados() {
		return txtCantidadPuntosIngresados;
	}

	public void setTxtCantidadPuntosIngresados(
			TextField txtCantidadPuntosIngresados) {
		this.txtCantidadPuntosIngresados = txtCantidadPuntosIngresados;
	}

	/************************************************************/
	/*********************** CONSTRUCTOR ************************/
	/************************************************************/

	public PolinomioControlador() {

	}

	/************************************************************/
	/******************** METODOS PRIVADOS **********************/
	/************************************************************/

	/**
	 * Le pide al controlador que obtenga el soporte asociado con los pares
	 * ordenados ingresados por el usuario de la vista
	 */
	private List<ParOrdenado> obtenerListaSoporte() {
		for (Controlador controller : main.getControladores()) {
			if (controller instanceof SoporteControlador) {
				controller = (SoporteControlador) controller;
				return ((SoporteControlador) controller).getSoporteData();
			}
		}
		return null;
	}

	/************************************************************/
	/********************* EVENT HANDLERS ***********************/
	/************************************************************/

	@FXML
	private void initialize() {

		ObservableList<String> metodosInterpolacion = FXCollections
				.observableArrayList();
		metodosInterpolacion.add("Newton-Gregory");
		metodosInterpolacion.add("Lagrange");

		this.cmbMetodoInterpolacion.setItems(metodosInterpolacion);
		this.cmbMetodoInterpolacion.getSelectionModel().select(0);

		ObservableList<String> cotasMaximasError = FXCollections
				.observableArrayList();
		cotasMaximasError.add("10^-2");
		cotasMaximasError.add("10^-3");
		cotasMaximasError.add("10^-4");
		cotasMaximasError.add("10^-5");
		cotasMaximasError.add("10^-6");
		cotasMaximasError.add("10^-7");
		cotasMaximasError.add("10^-8");

		this.cmbCotaMaximaError.setItems(cotasMaximasError);
		this.cmbCotaMaximaError.getSelectionModel().select(0);
		this.cmbCotaMaximaError.setDisable(true);

		this.consolaPolinomios.setStyle("-fx-text-fill: black;"
				+ "-fx-font: Arial;" + "-fx-font-size: 20;");

		this.txtCantidadPuntosIngresados.setStyle("-fx-text-fill: black;"
				+ "-fx-font: Arial;" + "-fx-font-size: 20;");

		this.txtGradoPolinomio.setStyle("-fx-text-fill: black;"
				+ "-fx-font: Arial;" + "-fx-font-size: 20;");
	}

	@FXML
	private void handleCalcularPolinomio() {

		if (this.obtenerListaSoporte().size() > 0) {
			this.polinomio = new PolinomioInterpolante();
			Soporte soporte = new Soporte(obtenerListaSoporte());
			this.polinomio.setSoporteAsociado(soporte);
			this.consolaPolinomios.setText(this.polinomio.resolverExpresion());
			this.txtGradoPolinomio.setText(polinomio.resolverGradoPolinomio());
		} else {
			String mensajeError = "El soporte no puede estar vacio";
			// Show the error message
			Dialogs.showErrorDialog(this.getMain().getEscenario(),
					mensajeError, "Imposible calcular el polinomio", "Presta atencion!");

		}

	}

	@FXML
	private void handleEvaluarPolinomio() {

		if (polinomio != null)
			this.main.cargarEvaluarPolinomioLayout(polinomio);
		else {
			String mensajeError = "Debe calcular el polinomio para poder evaluarlo en un punto";
			// Show the error message
			Dialogs.showErrorDialog(this.getMain().getEscenario(),
					mensajeError, "Imposible evaluar el polinomio", "Presta atencion!");

		}

	}

	@FXML
	private void handleGraficarPolinomio() {
		if (polinomio != null)
			this.main.cargarGraficoPolinomioLayout(polinomio);
		else {
			String mensajeError = "Debe calcular el polinomio para poder graficarlo";
			// Show the error message
			Dialogs.showErrorDialog(this.getMain().getEscenario(),
					mensajeError, "Imposible graficar el polinomio", "Presta atencion!");

		}
	}

	@FXML
	private void handleLimpiarTodo() {
		this.txtCantidadPuntosIngresados.clear();
		this.txtGradoPolinomio.clear();
		this.consolaPolinomios.clear();

		for (Controlador controller : this.main.getControladores()) {
			if (controller instanceof SoporteControlador) {
				controller = (SoporteControlador) controller;
				((SoporteControlador) controller).getTablaSoporte().getItems()
						.clear();
				((SoporteControlador) controller).getTextFieldX()
						.requestFocus();

			}
		}
	}

	@FXML
	private void handleCheckboxTruncarValores() {
		if (checkboxTruncarValores.isSelected())
			cmbCotaMaximaError.setDisable(false);

		if (!checkboxTruncarValores.isSelected())
			cmbCotaMaximaError.setDisable(true);
	}
}
